<!--
 * @Author: chenyulei yulei.chen@fa-software.com
 * @Date: 2023-12-12 14:32:07
 * @LastEditors: chenyulei yulei.chen@fa-software.com
 * @LastEditTime: 2023-12-15 15:07:22
 * @FilePath: /mycim4-oms-ui/src/components/TableSelect/index.vue
 * @Description: 下拉表格组件
-->
<template>
  <el-select
    ref="selectRef"
    v-model="select"
    :disabled="props.disabled"
    :size="props.size"
    :placeholder="props.placeholder"
    :clearable="clearable"
    class="table-select"
    :filterable="props.filterable"
    :filter-method="props.filterMethod || filterMethod"
    @clear="clearSelectValue"
  >
    <template #empty>
      <div
        v-loading="props.loading"
        class="cim-select-table"
        :style="{ width: `${props.tableWidth}px` }"
      >
        <vxe-table
          ref="tableRef"
          :height="tableHeight"
          stripe
          :border="props.border"
          :align="props.align"
          :data="tableData"
          :scroll-y="props.scrollY"
          :radio-config="{
            highlight: true,
            checkRowKey: defaultCheckRow
          }"
          :row-config="{ keyField: props.rowFieldKey }"
          @cell-click="setSelectRow"
        >
          <vxe-column
            v-for="item in props.columns"
            :key="item.field"
            :field="item.field"
            :type="item.type"
            :width="item.width"
            :title="item.title"
          />
        </vxe-table>
      </div>
    </template>
  </el-select>
</template>

<script setup lang="ts">
import { ref, computed, type Ref } from "vue";
import type { Props } from "./types";

defineOptions({
  name: "TableSelect"
});

// #region props
const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  placeholder: "请选择",
  size: "default",
  showKey: "name",
  filterable: true,
  filterKey: "name",
  filterCaseSensitive: true,
  tableWidth: 600,
  tableHeight: 160,
  border: true,
  align: "left",
  loading: false,
  rowFieldKey: "id",
  data: []
});
// #endregion

//#region emit
interface Emits {
  (e: "update:modelValue", val: any): void;
  (e: "change", val: any): void;
  (e: "clear", val: any): void;
}
const emit = defineEmits<Emits>();
//#endregion

// #region  ref dom
const selectRef = ref();
const tableRef = ref();
// #endregion

// #region data
const clearable: Ref<boolean> = ref(true);

// 表格全数据
const tableData = ref(props.data);
// #endregion

// #region computed
// 默认选中的表格行数据
const defaultCheckRow = computed(() => props.modelValue?.[props.rowFieldKey]);

// 选中的表格数据
const selectRow = computed({
  get() {
    return props.modelValue;
  },
  set(val: any) {
    emit("update:modelValue", val);
  }
});

// select展示的数据
const select = computed({
  get() {
    return selectRow.value?.[props.showKey];
  },
  set() {}
});

// #endregion
/**
 * @description 筛选对应filterKey值符合输入的数据 根据参数filterCaseSensitive确认是否区分大小选筛选
 * @param e
 * @returns any[]
 */
const filterMethod = (e: string) => {
  tableData.value = props.data.filter(item => {
    return props.filterCaseSensitive
      ? item[props.filterKey].indexOf(e) !== -1
      : item[props.filterKey].toLowerCase().indexOf(e.toLowerCase()) !== -1;
  });
};

/**
 * @description 设置表格选中 样式/数据
 * @param table
 * @returns
 */
const setTableSelect = (table: any) => {
  const $table = tableRef.value;
  if ($table) {
    $table.setRadioRow(props.data[table.rowIndex]);
  }
};

/**
 * @description 取消表格数据选中
 * @returns
 */
const clearTableSelect = () => {
  const $table = tableRef.value;
  if ($table) {
    selectRow.value = null;
    // 清除表格选中状态
    $table.clearRadioRow();
  }
};

/**
 * @description 单元格点击 设置选中/取消选中状态
 * @param table
 * @returns
 */
const setSelectRow = (table: any) => {
  const row = table.row;
  // 判断是选中还是取消选中 点击的数据等于当前选中的数据 取消 否则是选中
  if (
    selectRow.value &&
    row[props.rowFieldKey] === selectRow.value[props.rowFieldKey]
  ) {
    clearTableSelect();
  } else {
    // 设置选中的行数据
    selectRow.value = row;
    // 设置表格选中状态
    setTableSelect(table);
    emit("change", selectRow.value);
  }
};

/**
 * @description 从下拉框清空选中数据
 * @returns
 */
const clearSelectValue = () => {
  emit("clear", selectRow.value);
  selectRow.value = null;
};

/**
 * @description 使select下拉选择器聚焦
 */
const focus = () => {
  selectRef.value.focus();
};

/**
 * @description 使select下拉选择器失焦
 */
const blur = () => {
  selectRef.value.blur();
};

defineExpose({
  focus,
  blur
});
</script>
<style lang="scss">
.cim-select-table {
  user-select: none;
  --vxe-table-border-color: #dcdcdc;
  --vxe-table-header-background-color: #ededed;
  --vxe-table-header-font-weight: 500;
  --vxe-table-header-font-color: #333;
  --vxe-table-row-hover-background-color: #b6d0ee;
  --vxe-table-row-radio-checked-background-color: #b6d0ee;
  --vxe-table-row-hover-radio-checked-background-color: #b6d0ee;
  --vxe-table-row-striped-background-color: #f6f6f6;
  --vxe-table-row-hover-striped-background-color: #b6d0ee;
  --vxe-font-color: #1d1d1d;
  --vxe-table-column-padding-medium: 5px 0;

  .vxe-table--render-default.border--full .vxe-header--column,
  .vxe-table--render-default.border--full .vxe-body--column,
  .vxe-table--render-default.border--full .vxe-footer--column {
    background-image: linear-gradient(
      var(--vxe-table-border-color),
      var(--vxe-table-border-color)
    );
    background-position: unset;
  }

  .vxe-table .vxe-table--header-wrapper .vxe-table--header-border-line {
    border-bottom: 0;
  }

  .vxe-table--render-default .vxe-table--border-line {
    border: 0;
  }
}
</style>
